import { nextTick, ref, shallowRef, watch } from "vue"
import { useRouter } from "vue-router"
import { findPinYin } from "/plugins/pinyin"
import { useMenuStore } from "/store/menu"
import { useKeyHandleStore } from "/store/keyHandle"
const WINDOW_HEIGHT = window.innerHeight
const TOP_HEIGHT = 188
const BOTTOM_HEIGHT = 57
const RESULT_HEIGHT = WINDOW_HEIGHT - TOP_HEIGHT - BOTTOM_HEIGHT
const REAL_BOTTOM = WINDOW_HEIGHT - BOTTOM_HEIGHT
function formatSelectLaber(item) {
	const title = [].concat(item.parent.title)
	title.shift()
	if (title.length) {
		return title.join(" - ") + " - " + item.title
	}
	return item.title
}
export function useSearchBar(visible) {
	const menuStore = useMenuStore()
	const keyHandleStore = useKeyHandleStore()
	const router = useRouter()
	const result = shallowRef()
	const searchInput = shallowRef()
	const keyword = shallowRef("")
	const active = shallowRef(-1)
	const flattenMenuList = ref([])
	const instructMenuList = ref([])
	const formatMenuList = () =>
		menuStore.flattenMenuList
			.map(item => {
				return {
					value: item.title + "-" + item.path,
					label: formatSelectLaber(item),
					path: item.path,
					icon: item.icon,
					title: item.title,
				}
			})
			.filter(item => item.path)
	let flattenMenuListTotal = formatMenuList()
	flattenMenuList.value = [].concat(flattenMenuListTotal)
	let timer
	function filterMethod() {
		clearTimeout(timer)
		active.value = -1
		if (!keyword.value) {
			flattenMenuList.value = flattenMenuListTotal
			instructMenuList.value = []
			return
		}
		const queryRegExp = new RegExp(keyword.value, "i")
		flattenMenuList.value = flattenMenuListTotal.filter(
			item => findPinYin(item.label, keyword.value) || queryRegExp.test(item.path)
		)
		timer = setTimeout(async () => {
			instructMenuList.value = await getInstructMenu(keyword.value)
		}, 300)
	}
	//查询指令菜单
	async function getInstructMenu(label) {
		return await getAxios("/system/instructMenu/filter", { filterInfo: label })
	}
	function closeSearchBar() {
		visible.value = false
		setTimeout(() => {
			keyword.value = ""
			active.value = -1
			result.value && (result.value.scrollTop = 0)
			filterMethod()
		}, 250)
	}
	async function arrowKeyHandle(event) {
		if (event.key === "ArrowDown") {
			active.value = Math.min(active.value + 1, flattenMenuList.value.length - 1)
		} else if (event.key === "ArrowUp") {
			active.value = Math.max(active.value - 1, 0)
		}
		await nextTick()
		const item = document.querySelector(".search-bar .result .item.active")
		if (item && result.value) {
			if (item.getBoundingClientRect().top < TOP_HEIGHT) {
				result.value.scrollTop -= RESULT_HEIGHT * 0.9
			} else if (item.getBoundingClientRect().bottom >= REAL_BOTTOM) {
				result.value.scrollTop += RESULT_HEIGHT * 0.9
			}
		}
	}
	function enterKeyHandle() {
		if (active.value < 0) return
		if (active.value < instructMenuList.value.length) {
			router.push(instructMenuList.value[active.value].path)
		} else {
			router.push(flattenMenuList.value[active.value - instructMenuList.value.length].path)
		}
		closeSearchBar()
	}
	function setKeyHandle() {
		keyHandleStore.addKeyHandle("arrowKey", arrowKeyHandle, ["ArrowDown", "ArrowUp"], ["prevent"])
		keyHandleStore.addKeyHandle("enterKey", enterKeyHandle, ["Enter"], ["prevent"])
		keyHandleStore.addKeyHandle("escKey", closeSearchBar, ["Escape"], ["prevent"])
	}
	function removeKeyHandle() {
		keyHandleStore.removeKeyHandle("arrowKey")
		keyHandleStore.removeKeyHandle("enterKey")
		keyHandleStore.removeKeyHandle("escKey")
	}
	keyHandleStore.addKeyHandle(
		"openSearchBarCtrlK",
		() => {
			visible.value = true
		},
		["k"],
		["ctrl", "prevent"]
	)
	keyHandleStore.addKeyHandle(
		"openSearchBarAltS",
		() => {
			visible.value = true
		},
		["s"],
		["alt", "prevent"]
	)
	watch(
		visible,
		visible => {
			if (visible) {
				if (!flattenMenuListTotal.length) {
					flattenMenuListTotal = formatMenuList()
				}
				flattenMenuList.value = [].concat(flattenMenuListTotal)
				instructMenuList.value = []
				setKeyHandle()
				searchInput.value && searchInput.value.focus()
			} else {
				removeKeyHandle()
			}
		},
		{
			immediate: true,
		}
	)
	return {
		result,
		searchInput,
		keyword,
		active,
		flattenMenuList,
		instructMenuList,
		closeSearchBar,
		filterMethod,
	}
}
